﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace graphical_function_explorer.CalculationLogic
{
    public static class CalculationController
    {
        private static int NR_OF_VALUES = 10;               // Provisorial

        public static double[] CalculateValues(string equation)
        {
            double[] values = new double[NR_OF_VALUES];

            for (int q = 0; q < NR_OF_VALUES; q++)
                values[q] = CalculateValue(
                    equation.Replace(
                        ItemProvider.GetFunctionVariable(ItemProvider.GetLastMainVariable()).ToString(),
                        q.ToString()
                    )
                );

            return values;
        }

        private static double CalculateValue(string filledEquation)
        {
            double result = 0;
            string actualFilledEquation = filledEquation;

            while (actualFilledEquation.Contains('*') || actualFilledEquation.Contains('/'))          // maybe I should try to do it with a recursion (?)
                actualFilledEquation = ExecuteMultiplicationsAndDivisions(actualFilledEquation);
            while (actualFilledEquation.Contains('+') || actualFilledEquation.Contains('-'))
                actualFilledEquation = ExecuteAdditionsAndSubtractions(actualFilledEquation);

            result = Convert.ToDouble(actualFilledEquation);

            return result;
        }

        private static string ExecuteMultiplicationsAndDivisions(string filledEquation)
        {
            string equation = filledEquation;

            char actualOperation = 'm';

            int opPos;
            int begNum1;
            int endNum2;

            for (opPos = 0; opPos < equation.Length; opPos++)
            {
                if (equation[opPos] == '*')
                    break;
                else if (equation[opPos] == '/')
                {
                    actualOperation = 'd';
                    break;
                }
            }

            for (begNum1 = opPos - 1; begNum1 > 0; begNum1--)
            {
                if (equation[begNum1] == '+' || equation[begNum1] == '-')
                {
                    begNum1++;
                    break;
                }
            }

            for (endNum2 = opPos + 1; endNum2 < equation.Length; endNum2++)
            {
                if (equation[endNum2] == '+' || equation[endNum2] == '-' || equation[endNum2] == '*' || equation[endNum2] == '/')
                    break;
            }
            endNum2--;

            int substringLengthNum1 = opPos - begNum1;
            int substringLengthNum2 = endNum2 - opPos;
            int substringLength = endNum2 - begNum1 + 1;
            
            string num1Str = equation.Substring(begNum1, substringLengthNum1);
            string num2Str = equation.Substring(opPos + 1, substringLengthNum2);

            double num1Dou = Convert.ToDouble(num1Str);
            double num2Dou = Convert.ToDouble(num2Str);

            double result;
            if (actualOperation == 'm')
                result = num1Dou * num2Dou;
            else
                result = num1Dou / num2Dou;
            
            equation = equation.Remove(begNum1, substringLength).Insert(begNum1, result.ToString());
            
            return equation;
        }

        private static string ExecuteAdditionsAndSubtractions(string filledEquation)
        {
            string equation = filledEquation;

            char actualOperation = 'a';

            int opPos;
            int begNum1 = 0;    // " = 0" is just provisorial
            int endNum2;

            for (opPos = 0; opPos < equation.Length; opPos++)
            {
                if (equation[opPos] == '+')
                    break;
                else if (equation[opPos] == '-')
                {
                    actualOperation = 's';
                    break;
                }
            }

            // TO DO: Check if this part is needed
            /*for (begNum1 = opPos - 1; begNum1 > 0; begNum1--)           
            {
                if (equation[begNum1] == '+' || equation[begNum1] == '-')
                {
                    begNum1++;
                    break;
                }
            }*/

            for (endNum2 = opPos + 1; endNum2 < equation.Length; endNum2++)
            {
                if (equation[endNum2] == '+' || equation[endNum2] == '-')
                    break;
            }
            endNum2--;

            int substringLengthNum1 = opPos - begNum1;
            int substringLengthNum2 = endNum2 - opPos;
            int substringLength = endNum2 - begNum1 + 1;

            string num1Str = equation.Substring(begNum1, substringLengthNum1);
            string num2Str = equation.Substring(opPos + 1, substringLengthNum2);
            Console.WriteLine("equation = " + equation);
            double num1Dou = Convert.ToDouble(num1Str); // Error due to single negative number when subtracting (y=5-x)
            double num2Dou = Convert.ToDouble(num2Str);

            double result;
            if (actualOperation == 'a')
                result = num1Dou + num2Dou;
            else
                result = num1Dou - num2Dou;

            equation = equation.Remove(begNum1, substringLength).Insert(begNum1, result.ToString());

            return equation;
        }
    }
}
